<cfcomponent output="false">
	
	<!--- --->
	
	<cffunction name="add" access="public" output="true" returntype="void">
		<cfargument name="name" required="true" hint="file name" />
		<cfargument name="time" required="false" default="#now()#" />
		<cfargument name="method" required="true" />
		<cfargument name="args" required="false" default="#structNew()#" />
		<cfargument name="cfcatch" required="false" default="#structNew()#" />
		
		<cfset var local = {} />
		
		<cfif not structKeyExists(request,"session")>
			<cfset request.session = {} />
		</cfif>
		<cfif not structKeyExists(request.session,"user")>
			<cfset request.session.user = {id:""} />
		</cfif>
		
		<cfif arguments.method eq "">
			<cfset arguments.method = "no method" />
		</cfif>
				
		<cftry>
			<cfset local.args = serialize(sanitizeStruct(arguments.args,'$,$gateway,$view,$service,$controller')) />
			<cfif not structKeyExists(request,"session")>
				<cfset $.run.it('craftivityController.logout') />
			</cfif>
			<cfset local.session = serialize(request.session) />
			<cfset local._cfcatch = serialize(arguments.cfcatch) />
			
			<cfif len(local.args) gt 16000000>
				<cfset local.args = left(local.args,50000) />
			</cfif>
			<cfif len(local.session) gt 16000000>
				<cfset local.session = left(local.session,50000) />
			</cfif>
			<cfif len(local._cfcatch) gt 16000000>
				<cfset local._cfcatch = left(local._cfcatch,50000) />
			</cfif>
						
			<!--- now save to database --->
			<cfset application.helpers.database.save(
				table="craftivity_log",
				id="",
				name=trim(arguments.name),
				user_id=request.session.user.id,
				message=arguments.method,
				session=local.session,
				arguments=local.args,
				error=local._cfcatch
			) />
						
			<cfcatch>
				<!--- get rid of sql --->
				<cfset local._cfcatch = cfcatch />
				<cfset local._cfcatch.additional = "removed" />
				<cfset local._cfcatch.queryError = "removed" />
				<cfset arguments.cfcatch = {} />
				<!--- <cfset structDelete(cfcatch,"sql") /> --->

				<cfif structKeyExists(local._cfcatch,"sql")>
					<cfset local._cfcatch.sql = rereplace(local._cfcatch.sql,"\\","","ALL") />
				</cfif>
				
				<cftry>
					<!--- log an error if log service fails --->
					<cfset arguments.testID = application.helpers.database.save(
						table="craftivity_log",
						id="",
						name="log_error",
						session=local.session,
						user_id=request.session.user.id
						,message="Error Saving Log: " & arguments.method
						,error=serialize(local._cfcatch)
						,arguments=serialize(arguments)
					) />
					<cfcatch>
						<cfset arguments.testID = application.helpers.database.save(
							table="craftivity_log",
							id="",
							name="log_error",
							user_id=request.session.user.id
							,message="DoubleError Saving Log: " & arguments.method
						) />
					</cfcatch>
				</cftry>

				<cfif application.devmode>
					<cfrethrow />
				</cfif>
			</cfcatch>
		</cftry>
	</cffunction>
	
	<!--- --->
	
	<cffunction name="sanitizeStruct" access="public" output="false" returntype="struct">
		<cfargument name="struct" required="true" />
		<cfargument name="exclude" required="false" default="" />
		
		<cfset var local = {} />
		
		<cfset local.struct = structCopy(arguments.struct) />
		<cfloop list="#arguments.exclude#" index="local.i">
			<cfset structDelete(local.struct,local.i) />
		</cfloop>
		
		<cfreturn local.struct />
		
	</cffunction>
	
	<!--- --->
	
	<cffunction name="sanitizeArray" access="public" output="true" returntype="array">
		<cfargument name="array" required="true" />
		
		<cfset var local = {} />
		
		<cfloop array="#arguments.array#" index="local.i" item="local.item">
			<cfif isStruct(local.item)>
				<cfset arguments.array[local.i] = sanitizeStruct(arguments.array[local.i]) />
			<cfelseif isArray(local.item)>
				<cfset arguments.array[local.i] = sanitizeArray(arguments.array[local.i]) />
			<cfelseif isSimpleValue(local.item)>
				<cfset arguments.array[local.i] = sanitizePrimitive(arguments.array[local.i]) />
			<cfelse>
				<cfset arguments.array[local.i] = "!value removed by $.log!" />
			</cfif>
		</cfloop>
		
		<cfreturn arguments.array />
		
	</cffunction>
	
	<!--- --->
	
	<cffunction name="sanitizePrimitive" access="public" output="false" returntype="string">
		<cfargument name="primitive" required="true" />
		
		<cfset var local = {} />
		
		<cfset local.value = arguments.primitive />
		
		<!--- <cfset local.value = rereplace(local.value,'\\','\','ALL') /> --->
		<cfset local.value = rereplace(local.value,'\"','\"','ALL') />
		<cfset local.value = rereplace(local.value,"\'","\'",'ALL') />
		<!--- <cfset local.value = rereplace(local.value,"{","\{",'ALL') />
		<cfset local.value = rereplace(local.value,"}","\}",'ALL') /> --->
		<!--- <cfset local.value = rereplace(local.value,"\]","\]",'ALL') />
		<cfset local.value = rereplace(local.value,"\[","\[",'ALL') /> --->
		<!--- <cfset local.value = rereplace(local.value,"##","####",'ALL') /> --->
		
		<cfreturn local.value />
		
	</cffunction>
	
	<!--- --->

</cfcomponent>